home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / st80_pr4.lha / st80_pre4 / Foible / SDS / SDS-Graphs.st < prev    next >
Text File  |  1993-07-24  |  27KB  |  1,048 lines

  1. Model subclass: #Graph
  2.     instanceVariableNames: 'label plotVariables timeVariable graphBox graphOffset form view '
  3.     classVariableNames: ''
  4.     poolDictionaries: ''
  5.     category: 'SDS-Graphs'!
  6. Graph comment:
  7. 'I am a model for two dimension graph.
  8.  
  9. Instance variables:
  10.     label    <String>
  11.         label to appear in graph window
  12.     plotVariables <OrderedCollection of PlotVariable>
  13.         what dependence variables to draw in graph (y axis values)
  14.     timeVariable <TimeVariable>
  15.         time definition to draw as x axis
  16.     graphBox    <Rectangular>
  17.         size of the graph drawing
  18.     graphOffset <Point>
  19.         offset of graphBox relative to the view.
  20. '!
  21.  
  22.  
  23. !Graph methodsFor: 'initialize'!
  24.  
  25. initialize
  26.     "initialize graph model, set all defaults"
  27.     
  28.     self form: (Form new extent: 550@300).
  29.     self graphBox: (0@0 extent: 400@200).
  30.     self graphOffset: 100@50.! !
  31.  
  32. !Graph methodsFor: 'displaying'!
  33.  
  34. display
  35.     "Draw everything to receiver form"
  36.     
  37.     self displayTimeScale.
  38.     self displayPlotScale.
  39.     self displayPlotVariableNames.
  40.     self plotVariables do:
  41.         [:aPlotVariable | aPlotVariable plotOn: self form].!
  42.  
  43. displayOn: aView 
  44.     "Display what already in form to aView"
  45.  
  46.     self form
  47.         displayOn: Display
  48.         at: (aView displayTransformation applyTo: 0 @ 0)
  49.         clippingBox: (aView displayTransformation applyTo: (0 @ 0 extent: 550 @ 300))
  50.         rule: Form over
  51.         mask: Form black!
  52.  
  53. displayPlotScale
  54.     "display plot scale on y axis"
  55.  
  56.     | aLine intervals translation aLine2 aLine4 aLine8 currentPoint numberOfPlotVariables maxPoint minPoint |
  57.     aLine := Line new.
  58.     aLine beginPoint: self graphOffset - (1 @ 0).
  59.     aLine endPoint: self graphOffset + (-1 @ self graphBox extent y).
  60.     aLine
  61.         displayOn: form
  62.         at: 0 @ 0
  63.         clippingBox: form boundingBox
  64.         rule: Form over
  65.         mask: Form black.
  66.     aLine
  67.         displayOn: form
  68.         at: graphBox extent x @ 0
  69.         clippingBox: form boundingBox
  70.         rule: Form over
  71.         mask: Form black.
  72.     aLine2 := Line new.
  73.     aLine2 endPoint: -2 @ 0.
  74.     aLine4 := Line new.
  75.     aLine4 endPoint: -4 @ 0.
  76.     aLine8 := Line new.
  77.     aLine8 endPoint: -8 @ 0.
  78.     intervals := 32.
  79.     translation := aLine beginPoint - aLine endPoint / intervals.
  80.     currentPoint := aLine beginPoint.
  81.     0 to: intervals do: 
  82.         [:index | 
  83.         (index rem: 4)
  84.             = 0
  85.             ifTrue: 
  86.                 [aLine8
  87.                     displayOn: form
  88.                     at: currentPoint
  89.                     clippingBox: form boundingBox
  90.                     rule: Form over
  91.                     mask: Form black.
  92.                 aLine8
  93.                     displayOn: form
  94.                     at: currentPoint + ((8 + graphBox extent x)  @ 0)
  95.                     clippingBox: form boundingBox
  96.                     rule: Form over
  97.                     mask: Form black]
  98.             ifFalse: [(index rem: 2)
  99.                     = 0
  100.                     ifTrue: 
  101.                         [aLine4
  102.                             displayOn: form
  103.                             at: currentPoint
  104.                             clippingBox: form boundingBox
  105.                             rule: Form over
  106.                             mask: Form black.
  107.                         aLine4
  108.                             displayOn: form
  109.                             at: currentPoint + ((4 + graphBox extent x) @ 0)
  110.                             clippingBox: form boundingBox
  111.                             rule: Form over
  112.                             mask: Form black]
  113.                     ifFalse: 
  114.                         [aLine2
  115.                             displayOn: form
  116.                             at: currentPoint
  117.                             clippingBox: form boundingBox
  118.                             rule: Form over
  119.                             mask: Form black.
  120.                         aLine2
  121.                             displayOn: form
  122.                             at: currentPoint + ((2 + graphBox extent x) @ 0)
  123.                             clippingBox: form boundingBox
  124.                             rule: Form over
  125.                             mask: Form black]].
  126.         currentPoint := currentPoint - translation].
  127.     numberOfPlotVariables := self plotVariables size.
  128.     maxPoint := 5 @ (graphOffset y - (numberOfPlotVariables * 7) + 6).
  129.     minPoint := maxPoint + (0 @ self graphBox extent y).
  130.     translation := 0 @ 14.
  131.     self plotVariables do: 
  132.         [:aPlotVariable | 
  133.         aPlotVariable displayMinimumOn: self form at: minPoint; displayMaximumOn: self form at: maxPoint.
  134.         maxPoint := maxPoint translateBy: translation.
  135.         minPoint := minPoint translateBy: translation]!
  136.  
  137. displayPlotVariableNames
  138.     "display legend for plot variables"
  139.  
  140.     | index aPoint |
  141.     index := 0.
  142.     aPoint := 10@10.
  143.     self plotVariables do: 
  144.         [:aVar | 
  145.         aVar displayNameOn: self form at: aPoint.
  146.         index := index + 1 rem: 4.
  147.         index isZero
  148.             ifTrue: [aPoint := 10 @ (aPoint y + 15)]
  149.             ifFalse: [aPoint := aPoint + (125 @ 0)]]!
  150.  
  151. displayTimeScale
  152.     "Display time scale of reciever."
  153.  
  154.     self timeVariable
  155.         displayOn: self form
  156.         from: self graphOffset + (0 @ (self graphBox extent y + 1))
  157.         to: self graphOffset + self graphBox extent + (0 @ 1)! !
  158.  
  159. !Graph methodsFor: 'accessing'!
  160.  
  161. form
  162.     "Answer the form"
  163.  
  164.     ^form.!
  165.  
  166. form: aForm
  167.     "set form where to draw"
  168.  
  169.     form := aForm.!
  170.  
  171. graphBox
  172.     "Answer graphBox"
  173.  
  174.     ^graphBox.!
  175.  
  176. graphBox: aRectangle
  177.     "set graphBox size"
  178.  
  179.     graphBox := aRectangle.!
  180.  
  181. graphOffset
  182.     "Answer graphOffset"
  183.  
  184.     ^graphOffset.!
  185.  
  186. graphOffset: aPoint
  187.     "set graphOffset"
  188.  
  189.     graphOffset := aPoint.!
  190.  
  191. label
  192.     "Answer the label"
  193.  
  194.     ^label.!
  195.  
  196. label: aString 
  197.     "set label for graph"
  198.  
  199.     label := aString!
  200.  
  201. plotVariables
  202.     "Answer plotVariables Collection"
  203.  
  204.     ^plotVariables.!
  205.  
  206. plotVariables: aPlotVariableCollection
  207.     "Set plotVariables of receiver"
  208.  
  209.     plotVariables := aPlotVariableCollection.!
  210.  
  211. timeVariable
  212.     "Answer timeVar"
  213.  
  214.     ^timeVariable!
  215.  
  216. timeVariable: aTimeVariable
  217.     "Set timeVariable of receiver"
  218.  
  219.     timeVariable := aTimeVariable.!
  220.  
  221. view
  222.     "answer the corressponding view"
  223.  
  224.     ^view.!
  225.  
  226. view: aGraphView
  227.     "set corresponding view"
  228.  
  229.     view := aGraphView.! !
  230.  
  231. !Graph methodsFor: 'adding'!
  232.  
  233. addPlotVariable: aPlotVariable
  234.     "Add a plotVariable to plotVariables Collection"
  235.  
  236.     self plotVariables = nil
  237.         ifTrue: [self plotVariables: OrderedCollection new].
  238.     self plotVariables addLast: aPlotVariable.!
  239.  
  240. addPlotVariableWithName: aString minimum: minimumValue maximum: maximumValue data: anOC mask: aMask 
  241.     "Add a plotVariable to plotVariables Collection"
  242.  
  243.     | aPlotVariable minValue maxValue |
  244.     
  245.     minimumValue = maximumValue
  246.         ifTrue: [minValue _ minimumValue -1.
  247.                 maxValue _ maximumValue + 1]
  248.         ifFalse:[minValue _ minimumValue.
  249.                 maxValue _ maximumValue].
  250.     self timeVariable = nil
  251.         ifTrue: [self error: 'time range not defined']
  252.         ifFalse: 
  253.             [aPlotVariable := PlotVariable new.
  254.             aPlotVariable name: aString; minimum: minValue; maximum: maxValue.
  255.             aPlotVariable data: anOC.
  256.             aPlotVariable boundingBox: (self graphBox translateBy: self graphOffset).
  257.             aPlotVariable transformation: (WindowingTransformation window: (0 @ minValue corner: self timeVariable numberOfIntervals @ maxValue) viewport: self graphBox).
  258.             aPlotVariable mask: aMask.
  259.             self plotVariables = nil
  260.                 ifTrue: [self plotVariables: OrderedCollection new].
  261.             self plotVariables addLast: aPlotVariable.]!
  262.  
  263. addPlotVariableWithName: aString minimum: minValue maximum: maxValue mask: aMask 
  264.     "Add a plotVariable to plotVariables Collection"
  265.  
  266.     | aPlotVariable |
  267.     self timeVariable = nil
  268.         ifTrue: [self error: 'time range not defined']
  269.         ifFalse: 
  270.             [aPlotVariable := PlotVariable new.
  271.             aPlotVariable name: aString; minimum: minValue; maximum: maxValue.
  272.             aPlotVariable data: OrderedCollection new.
  273.             aPlotVariable boundingBox: (self graphBox translateBy: self graphOffset).
  274.             aPlotVariable transformation: (WindowingTransformation window: (0 @ minValue extent: self timeVariable numberOfIntervals @ maxValue) viewport: self graphBox).
  275.             aPlotVariable mask: aMask.
  276.             self plotVariables = nil
  277.                 ifTrue: [self plotVariables: OrderedCollection new].
  278.             self plotVariables addLast: aPlotVariable.]!
  279.  
  280. timeVariableWithMinimum: minValue maximum: maxValue delta: aDelta 
  281.     "Add a plotVariable to plotVariables Collection"
  282.  
  283.     | aTimeVariable |
  284.     aTimeVariable := TimeVariable new.
  285.     aTimeVariable name: 'Time'.
  286.     aTimeVariable minimum: minValue; maximum: maxValue; delta: aDelta.
  287.     self timeVariable: aTimeVariable.! !
  288. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  289.  
  290. Graph class
  291.     instanceVariableNames: ''!
  292.  
  293.  
  294. !Graph class methodsFor: 'mask constants'!
  295.  
  296. mask: aNumber
  297.         
  298.     aNumber = 0
  299.         ifTrue: [^Form black].
  300.     aNumber = 1
  301.         ifTrue: [^Form darkGray].
  302.     aNumber = 2
  303.         ifTrue: [^Form gray].
  304.     aNumber = 3
  305.         ifTrue: [^Form veryLightGray].! !
  306.  
  307. !Graph class methodsFor: 'user interface'!
  308.  
  309. example
  310.  
  311.     "example"
  312.  
  313.     "Graph example"
  314.     
  315.     | anOC aGraphVariable aGraph anOCOC anOC2 anOC3 |
  316.     aGraph := Graph new.
  317.     anOC := OrderedCollection new.
  318.     anOC add: 10; add: 20; add: 5; add: 15; add: 40; add: 50.
  319.     anOC2 := OrderedCollection new.
  320.     anOC2 add: 30; add: 40; add: 25; add: 40; add: 40; add: 90; add: 100; add: 20.
  321.     anOC3 := OrderedCollection new.
  322.     anOC3 add: 130; add: 240; add: 125; add: 540; add: 40; add: 590; add: 100; add: 20; add: 349.
  323.     aGraph graphBox: (0@0 extent: 400@200).
  324.     aGraph graphOffset: (50@50).
  325.     aGraphVariable := GraphVariable newWithLabel: 'test' minimum: 0 maximum: 100 data: anOC maxT: 5 deltaT: 1 graphBox: aGraph graphBox.
  326.     aGraphVariable mask: Form black.
  327.     anOCOC := OrderedCollection new.
  328.     anOCOC add: aGraphVariable.
  329.     aGraphVariable := GraphVariable newWithLabel: 'test23' minimum: 0 maximum: 100 data: anOC2 maxT: 7 deltaT: 1 graphBox: aGraph graphBox.
  330.     aGraphVariable mask: Form gray.
  331.     anOCOC add: aGraphVariable.
  332.     aGraphVariable := GraphVariable newWithLabel: 'test34' minimum: 100 maximum: 600 data: anOC3 maxT: 15 deltaT: 1 graphBox: aGraph graphBox.
  333.     aGraphVariable mask: Form darkGray.
  334.     anOCOC add: aGraphVariable.
  335.     aGraphVariable := GraphVariable newWithLabel: 'test56' minimum: 000 maximum: 900 data: anOC3 maxT: 40 deltaT: 1 graphBox: aGraph graphBox.
  336.     aGraphVariable mask: Form gray.
  337.     anOCOC add: aGraphVariable.
  338.     aGraphVariable := GraphVariable newWithLabel: 'test67' minimum: 80 maximum: 600 data: anOC3 maxT:  10 deltaT: 1 graphBox: aGraph graphBox.
  339.     aGraphVariable mask: Form darkGray.
  340.     anOCOC add: aGraphVariable.
  341.     aGraph dependentVars: anOCOC.
  342.     GraphView openOn:  aGraph.!
  343.  
  344. test
  345.     "Graph test"
  346.     
  347.     | aGraph |
  348.     aGraph := Graph new.
  349.     aGraph initialize.
  350.     aGraph label: 'Graph'.
  351.     aGraph timeVariableWithMinimum: 0 maximum: 100 delta: 5.
  352.     aGraph addPlotVariableWithName: 'test1' minimum: 0 maximum: 100 mask: Form black.
  353.     aGraph plotVariables first add: 10; add: 20; add: 10; add: 50; add:90; add:30; add:20.
  354.     aGraph display.
  355.     GraphView openOn: aGraph.! !
  356.  
  357. Object subclass: #GraphVariable
  358.     instanceVariableNames: 'name minimum maximum '
  359.     classVariableNames: ''
  360.     poolDictionaries: ''
  361.     category: 'SDS-Graphs'!
  362. GraphVariable comment:
  363. 'I am an abstract superclass for graph variables (either dependent variables for y axis, or independent variable for x axis)
  364.  
  365. Instance variables
  366.     name    <String>
  367.         variable name
  368.     minimum <Number>
  369.         minimum boundary to be shown in the graph
  370.     maximum <Number>
  371.         similar to above for maximum boundary'!
  372.  
  373.  
  374. !GraphVariable methodsFor: 'displaying'!
  375.  
  376. displayNameOn: aForm at: aPoint
  377.     "Display variable name."
  378.  
  379.     self name displayOn: aForm at: aPoint.! !
  380.  
  381. !GraphVariable methodsFor: 'accessing'!
  382.  
  383. maximum
  384.     "Answer maximum value of receiver"
  385.  
  386.     ^maximum!
  387.  
  388. maximum: maxValue
  389.     "Set maximum value of receiver"
  390.  
  391.     maximum := maxValue.!
  392.  
  393. minimum
  394.     "Answer minimum value of receiver"
  395.  
  396.     ^minimum!
  397.  
  398. minimum: minValue
  399.     "Set minimum value of receiver"
  400.  
  401.     minimum := minValue.!
  402.  
  403. name
  404.     "Answer name of variable "
  405.  
  406.     ^name.!
  407.  
  408. name: aString
  409.     "define the name of variable "
  410.  
  411.     name := aString.! !
  412.  
  413. GraphVariable subclass: #TimeVariable
  414.     instanceVariableNames: 'delta '
  415.     classVariableNames: ''
  416.     poolDictionaries: ''
  417.     category: 'SDS-Graphs'!
  418. TimeVariable comment:
  419. 'I define the x-axis values for the graph.
  420.     
  421. Instance variable:
  422.     delta <Number>
  423.         delta time '!
  424.  
  425.  
  426. !TimeVariable methodsFor: 'displaying'!
  427.  
  428. displayOn: aForm from: aPoint to: anotherPoint 
  429.     "display time scale on x axis"
  430.  
  431.     | aLine intervals translation aLine2 aLine4 aLine8 currentPoint aNumber |
  432.     aLine := Line new.
  433.     aLine beginPoint: aPoint; endPoint: anotherPoint.
  434.     aLine
  435.         displayOn: aForm
  436.         at: 0 @ 0
  437.         clippingBox: aForm boundingBox
  438.         rule: Form over
  439.         mask: Form black.
  440.     aLine2 := Line new.
  441.     aLine2 endPoint: 0 @ 2.
  442.     aLine4 := Line new.
  443.     aLine4 endPoint: 0 @ 4.
  444.     aLine8 := Line new.
  445.     aLine8 endPoint: 0 @ 8.
  446.     intervals := 32.
  447.     translation := anotherPoint - aPoint / intervals.
  448.     currentPoint := aPoint.
  449.     0 to: intervals do: 
  450.         [:index | 
  451.         (index rem: 4)
  452.             = 0
  453.             ifTrue: [aLine8
  454.                     displayOn: aForm
  455.                     at: currentPoint
  456.                     clippingBox: aForm boundingBox
  457.                     rule: Form over
  458.                     mask: Form black]
  459.             ifFalse: [(index rem: 2)
  460.                     = 0
  461.                     ifTrue: [aLine4
  462.                             displayOn: aForm
  463.                             at: currentPoint
  464.                             clippingBox: aForm boundingBox
  465.                             rule: Form over
  466.                             mask: Form black]
  467.                     ifFalse: [aLine2
  468.                             displayOn: aForm
  469.                             at: currentPoint
  470.                             clippingBox: aForm boundingBox
  471.                             rule: Form over
  472.                             mask: Form black]].
  473.         currentPoint := currentPoint + translation].
  474.     minimum printString displayOn: aForm at: aPoint + (-5 @ 10).
  475.     translation := translation * 8.
  476.     currentPoint := aPoint + (-10 @ 10).
  477.     aNumber := (maximum - minimum / 4) asFloat.
  478.     1 to: 3 do: 
  479.         [:index | 
  480.         currentPoint := currentPoint + translation.
  481.         (minimum + (index * aNumber)) printString displayOn: aForm at: currentPoint].
  482.     maximum printString displayOn: aForm at: anotherPoint + (-10 @ 10).
  483.     name displayOn: aForm at: aPoint + anotherPoint / 2 + (-10 @ 25)! !
  484.  
  485. !TimeVariable methodsFor: 'accessing'!
  486.  
  487. delta
  488.     "Answer delta X value of receiver"
  489.  
  490.     ^delta!
  491.  
  492. delta: aNumber
  493.     "Set delta X value of receiver"
  494.  
  495.     delta := aNumber.!
  496.  
  497. numberOfIntervals
  498.     "Answer number of intervals in time variable"
  499.  
  500.     ^self maximum - self minimum / self delta! !
  501.  
  502. GraphVariable subclass: #PlotVariable
  503.     instanceVariableNames: 'mask transformation boundingBox data '
  504.     classVariableNames: ''
  505.     poolDictionaries: ''
  506.     category: 'SDS-Graphs'!
  507. PlotVariable comment:
  508. 'I am a variable to be plotted in a graph (variable as y axis).
  509.  
  510. Instance variables
  511.     mask    <Form>
  512.         mask (''color'') for plotting my values
  513.     transformation <WindowingTransformation>
  514.         transform my values to point in the view
  515.     boundingBox <Rectangular>
  516.         clipping box of the plot line
  517.     data <OrderedCollection of Number>
  518.         my ordered values over time'!
  519.  
  520.  
  521. !PlotVariable methodsFor: 'adding'!
  522.  
  523. add: aValue
  524.     "Append a new value to receiver data"
  525.  
  526.     self data = nil
  527.         ifTrue: [self data: OrderedCollection new].
  528.     self data addLast: aValue.! !
  529.  
  530. !PlotVariable methodsFor: 'displaying'!
  531.  
  532. add: aValue plotOn: aDisplayMedium 
  533.     "add a new value and plot receiver on display medium."
  534.  
  535.     | aLine  baseY aPoint aBoundingBox lastIndex |
  536.     aBoundingBox := self boundingBox.
  537.     baseY := aBoundingBox extent y.
  538.     aPoint := aBoundingBox origin.
  539.     aLine := Line new.
  540.     aLine form: (Form dotOfSize: 2).
  541.     lastIndex := self data size - 1.
  542.     aLine beginPoint: (self transformation applyTo: lastIndex @ self data last).
  543.     aLine endPoint: (self transformation applyTo: lastIndex + 1 @ aValue).
  544.     aLine beginPoint y: baseY - aLine beginPoint y.
  545.     aLine endPoint y: baseY - aLine endPoint y.
  546.     aLine
  547.         displayOn: aDisplayMedium
  548.         at: aPoint
  549.         clippingBox: aBoundingBox
  550.         rule: Form over
  551.         mask: self mask.
  552.     self add: aValue.!
  553.  
  554. displayMaximumOn: aForm at: aPoint
  555.  
  556.     | aLine |
  557.     aLine := Line new.
  558.     aLine form: (Form dotOfSize: 2).
  559.     aLine beginPoint: 0@0; endPoint: 5@0.
  560.     aLine displayOn: aForm at: aPoint clippingBox: aForm boundingBox rule: Form over mask: self mask.
  561.     self maximum printString displayOn: aForm at: (aPoint + (8@-8)).!
  562.  
  563. displayMinimumOn: aForm at: aPoint
  564.  
  565.     | aLine |
  566.     aLine := Line new.
  567.     aLine form: (Form dotOfSize: 2).
  568.     aLine beginPoint: 0@0; endPoint: 5@0.
  569.     aLine displayOn: aForm at: aPoint clippingBox: aForm boundingBox rule: Form over mask: self mask.
  570.     self minimum printString displayOn: aForm at: (aPoint + (8@-8)).!
  571.  
  572. displayNameOn: aForm at: aPoint
  573.  
  574.     | aLine |
  575.     aLine := Line new.
  576.     aLine form: (Form dotOfSize: 2).
  577.     aLine beginPoint: 0@0; endPoint: 25@0.
  578.     aLine displayOn: aForm at: aPoint clippingBox: aForm boundingBox rule: Form over mask: self mask.
  579.     self name displayOn: aForm at: (aPoint + (30@-8)).!
  580.  
  581. plotOn: aDisplayMedium 
  582.     "Plot receiver on display medium."
  583.  
  584.     | aLine nextIndex nextPoint baseY aPoint aBoundingBox counter |
  585.     (data = nil) | (data size = 0) ifTrue: [^nil].
  586.     aBoundingBox := self boundingBox.
  587.     baseY := aBoundingBox extent y.
  588.     aPoint := aBoundingBox origin.
  589.     aLine := Line new.
  590.     aLine form: (Form dotOfSize: 2).
  591.     nextIndex := 0.
  592.     nextPoint := self transformation applyTo: nextIndex @ data first.
  593.     nextPoint y: baseY - nextPoint y.
  594.     counter := 1.
  595.     self data do: 
  596.         [:datum | 
  597.         counter < self data size
  598.             ifTrue: 
  599.                 [aLine beginPoint: nextPoint.
  600.                 nextIndex := nextIndex + 1.
  601.                 nextPoint := self transformation applyTo: nextIndex @ (data after: datum).
  602.                 nextPoint y: baseY - nextPoint y.
  603.                 aLine endPoint: nextPoint.
  604.                 aLine
  605.                     displayOn: aDisplayMedium
  606.                     at: aPoint
  607.                     clippingBox: aBoundingBox
  608.                     rule: Form over
  609.                     mask: self mask].
  610.         counter := counter + 1]! !
  611.  
  612. !PlotVariable methodsFor: 'accessing'!
  613.  
  614. boundingBox
  615.     "Answer boundingBox of receiver"
  616.  
  617.     ^boundingBox.!
  618.  
  619. boundingBox: aRectangle
  620.     "Set boundingBox of receiver"
  621.  
  622.     boundingBox := aRectangle.!
  623.  
  624. data
  625.     "Answer ordered collection data of receiver"
  626.  
  627.     ^data.!
  628.  
  629. data: anOrderedCollection
  630.     "Set ordered collection data of receiver"
  631.  
  632.     data := anOrderedCollection.!
  633.  
  634. mask
  635.     "Answer mask information of receiver"
  636.  
  637.     ^mask.!
  638.  
  639. mask: aForm
  640.     "Set mask information of receiver"
  641.  
  642.     mask := aForm.!
  643.  
  644. transformation
  645.     "Answer transformation of receiver"
  646.  
  647.     ^transformation.!
  648.  
  649. transformation: aWindowingTransformation
  650.     "Set transformation of receiver"
  651.  
  652.     transformation := aWindowingTransformation.! !
  653.  
  654. Model subclass: #GraphList
  655.     instanceVariableNames: 'currentBox boxes '
  656.     classVariableNames: 'BoxMenu '
  657.     poolDictionaries: ''
  658.     category: 'SDS-Graphs'!
  659. GraphList comment:
  660. 'I am the model for editing graph parameters (what variables to appear in graph and what  their the minimum / maximum boundaries).
  661.  
  662. Instance variables:
  663.     boxes <OrderedCollection of SDSBox-es>
  664.         holds what boxes already enrolled to appear in graph
  665.     currentBox <String> 
  666.         current box''s name whose variable is being edited
  667.  
  668. Class variable:
  669.     BoxMenu <ActionMenu>
  670.         menu for the leftmost subview (the right part of the view is a MinMaxView)
  671.     '!
  672.  
  673.  
  674. !GraphList methodsFor: 'box list'!
  675.  
  676. boxList
  677.     "Answer an Array of my boxes name"
  678.  
  679.     | anArray index |
  680.     anArray _ Array new: boxes size.
  681.     index _ 1.
  682.     boxes do: 
  683.         [:box | 
  684.         anArray at: index put: box name.
  685.         index _ index + 1].
  686.     ^anArray!
  687.  
  688. boxMenu
  689.     "Answer box menu"
  690.  
  691.     BoxMenu = nil ifTrue: [BoxMenu _ ActionMenu labels: 'delete' selectors: #(#deleteBox )].
  692.     ^BoxMenu!
  693.  
  694. boxValue
  695.     "Answer my box whose name is equal to currentBox"
  696.  
  697.     boxes do: [:box | box name asString = currentBox ifTrue: [^box]].
  698.     ^nil!
  699.  
  700. currentBox
  701.     ^currentBox!
  702.  
  703. currentBox: aSelection 
  704.     currentBox _ aSelection.
  705.     self changed: #forBox: with: self boxValue.! !
  706.  
  707. !GraphList methodsFor: 'accessing'!
  708.  
  709. boxes
  710.     ^boxes!
  711.  
  712. boxes: anOCBoxes
  713.     boxes _ anOCBoxes! !
  714.  
  715. !GraphList methodsFor: 'private-menu messages'!
  716.  
  717. deleteBox
  718.     "delete currentBox"
  719.  
  720.     boxes remove: self boxValue ifAbsent: [^nil].
  721.     self changed: #currentBox! !
  722. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  723.  
  724. GraphList class
  725.     instanceVariableNames: ''!
  726.  
  727.  
  728. !GraphList class methodsFor: 'instance creation'!
  729.  
  730. withBoxes: anOCBoxes 
  731.     "Answer an instance of the receiver on the model, aGraphList. 
  732.     The label is aString. Do not terminate the current active process."
  733.  
  734.     | topView aGraphList aMinMaxEditor |
  735.     aGraphList _ GraphList new.
  736.     aGraphList boxes: anOCBoxes.
  737.     aMinMaxEditor _ MinMaxEditor new.
  738.     aGraphList addDependent: aMinMaxEditor.
  739.     topView _ StandardSystemView
  740.                 model: aGraphList
  741.                 label: 'List of Plotted Variables'
  742.                 minimumSize: 300 @ 100.
  743.     topView
  744.         addSubView: (SelectionInListView
  745.                 on: aGraphList
  746.                 printItems: true
  747.                 oneItem: false
  748.                 aspect: #currentBox
  749.                 change: #currentBox:
  750.                 list: #boxList
  751.                 menu: #boxMenu
  752.                 initialSelection: #currentBox)
  753.         in: (0 @ 0 extent: 0.4 @ 1)
  754.         borderWidth: 1.
  755.     MinMaxView
  756.         view: aMinMaxEditor
  757.         in: (0.4 @ 0 extent: 1 @ 1)
  758.         of: topView.
  759.     topView controller open.
  760.     ^topView! !
  761.  
  762. InspectorView subclass: #MinMaxView
  763.     instanceVariableNames: ''
  764.     classVariableNames: ''
  765.     poolDictionaries: ''
  766.     category: 'SDS-Graphs'!
  767. MinMaxView comment:
  768. 'View for editing the minimum and maximum boundaries of a variable in graph.
  769. I am part of triad MVC with MinMaxEditor(model) and MinMaxController(controller).'!
  770.  
  771.  
  772. !MinMaxView methodsFor: 'controller access'!
  773.  
  774. defaultController
  775.     ^model defaultControllerClass new.! !
  776. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  777.  
  778. MinMaxView class
  779.     instanceVariableNames: ''!
  780.  
  781.  
  782. !MinMaxView class methodsFor: 'private'!
  783.  
  784. buildScheduledView: aMinMaxEditor 
  785.     | topView |
  786.     topView _ self
  787.                 model: aMinMaxEditor
  788.                 label: 'Graph parameters for: ' , aMinMaxEditor box name
  789.                 minimumSize: 180 @ 180.
  790.     self
  791.         view: aMinMaxEditor
  792.         in: (0 @ 0 extent: 1 @ 1)
  793.         of: topView.
  794.     ^topView! !
  795.  
  796. StandardSystemView subclass: #GraphView
  797.     instanceVariableNames: ''
  798.     classVariableNames: ''
  799.     poolDictionaries: ''
  800.     category: 'SDS-Graphs'!
  801. GraphView comment:
  802. 'View for graph window.'!
  803.  
  804.  
  805. !GraphView methodsFor: 'displaying'!
  806.  
  807. display 
  808.     
  809.     self model displayOn: self.
  810.     self halt.!
  811.  
  812. displayView
  813.     
  814.     super displayView.
  815.     self halt.! !
  816. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  817.  
  818. GraphView class
  819.     instanceVariableNames: ''!
  820.  
  821.  
  822. !GraphView class methodsFor: 'instance creation'!
  823.  
  824. openOn: aGraph 
  825.     "Answer an instance of the receiver on the model"
  826.  
  827.     | topView aFormView |
  828.     "aGraph initialize."
  829.     topView := StandardSystemView
  830.                 model: aGraph
  831.                 label: aGraph label
  832.                 minimumSize: 554 @ 304.
  833.     aFormView := FormView new model: aGraph form controller: NoController new.
  834.     topView addSubView: aFormView.
  835.     topView borderWidth: 2.
  836.     "aGraph displayOn: aFormView."
  837.     topView controller open.
  838.     ^topView! !
  839.  
  840. Inspector subclass: #MinMaxEditor
  841.     instanceVariableNames: 'minimum maximum box '
  842.     classVariableNames: 'FieldList MinMaxTextMenu '
  843.     poolDictionaries: ''
  844.     category: 'SDS-Graphs'!
  845. MinMaxEditor comment:
  846. 'Model for editing the minimum and maximum boundary values to be shown in the graph.
  847.  
  848. Instance variables
  849.     minimum <Number>
  850.         current minimum value or a string ''default (X)'' where X is default
  851.         minimum value
  852.     maximum <Number>
  853.         current maximum value
  854.     box <SDSBox>
  855.         box which minimum/maximum values being defined
  856. '!
  857.  
  858.  
  859. !MinMaxEditor methodsFor: 'controller access'!
  860.  
  861. defaultControllerClass
  862.     "Answer the class of the default controller for the receiver."
  863.  
  864.     ^MinMaxController! !
  865.  
  866. !MinMaxEditor methodsFor: 'text'!
  867.  
  868. textMenu
  869.     "Answer an ActionMenu of operations on the text of the selected 
  870.     variable's value that is to be displayed when the operate menu 
  871.     button is pressed."
  872.  
  873.     MinMaxTextMenu == nil ifTrue: 
  874.         [MinMaxTextMenu _
  875.             ActionMenu
  876.                 labels: 'reset to default\again\undo\copy\cut\paste\do it\print it\inspect\accept\cancel' withCRs
  877.                 lines: #(1 3 6 9)
  878.                 selectors: #(#resetToDefault #again #undo #copySelection #cut #paste #doIt #printIt #inspectIt #accept #cancel )].
  879.     ^MinMaxTextMenu! !
  880.  
  881. !MinMaxEditor methodsFor: 'field list'!
  882.  
  883. fieldIndex
  884.     "Answer the offset corresponding to the currently selected field"
  885.     field = 'minimum'
  886.         ifTrue: [^1].
  887.     field = 'maximum'
  888.         ifTrue: [^2].
  889.     ^nil!
  890.  
  891. fieldList
  892.     "Answer an Array consisting of minimum and maximum."
  893.  
  894.     FieldList = nil
  895.         ifTrue: [FieldList _ Array with: 'minimum' with: 'maximum'].
  896.     ^FieldList.!
  897.  
  898. fieldMenu
  899.     "Answer an ActionMenu of operations on the variables that is to be displayed 
  900.     when the operate menu button is pressed."
  901.  
  902.     ^nil.!
  903.  
  904. fieldValue
  905.     "Answer the value of the currently selected variable."
  906.  
  907.     field = 'minimum' ifTrue: [^minimum].
  908.     field = 'maximum' ifTrue: [^maximum].
  909.     ^nil.! !
  910.  
  911. !MinMaxEditor methodsFor: 'menu messages'!
  912.  
  913. resetToDefault
  914.     | min aString max aStream |
  915.     field = 'minimum' ifTrue: [box minimumValueIsDefault
  916.             ifFalse: 
  917.                 [box minimumValue: nil.
  918.                 min _ box minimumValue.
  919.                 min = nil
  920.                     ifTrue: [aString _ 'default (known after simulation)']
  921.                     ifFalse: [aString _ 'default (' .
  922.                             aStream _ TextStream on: ''.
  923.                             min printOn: aStream.
  924.                             aString _ aString, aStream contents asString, ')'].
  925.                 minimum _ aString asSymbol]].
  926.     field = 'maximum' ifTrue: [box maximumValueIsDefault
  927.             ifFalse: 
  928.                 [box maximumValue: nil.
  929.                 max _ box maximumValue.
  930.                 max = nil
  931.                     ifTrue: [aString _ 'default (known after simulation)']
  932.                     ifFalse: [aString _ 'default (' .
  933.                             aStream _ TextStream on: ''.
  934.                             max printOn: aStream.
  935.                             aString _ aString, aStream contents asString, ')'].
  936.                 maximum _ aString asSymbol]].
  937.     self changed: #text.!
  938.  
  939. update
  940.     ^self!
  941.  
  942. updateBoxMinMaxValues
  943.     minimum isSymbol
  944.         ifTrue: ["set to default"
  945.             box minimumValue: nil]
  946.         ifFalse: [box minimumValue: minimum].
  947.     maximum isSymbol
  948.         ifTrue: ["set to default"
  949.             box maximumValue: nil]
  950.         ifFalse: [box maximumValue: maximum]! !
  951.  
  952. !MinMaxEditor methodsFor: 'initialize-release'!
  953.  
  954. forBox: aBox 
  955.     | min aString max aStream |
  956.     aBox = nil
  957.         ifTrue: [^nil].
  958.     box _ aBox.
  959.     aBox minimumValueIsDefault
  960.         ifTrue: 
  961.             [min _ box minimumValue.
  962.             min = nil
  963.                 ifTrue: [aString _ 'default (known after simulation)']
  964.                 ifFalse: [aStream _ TextStream on: ''.
  965.                         min printOn: aStream.
  966.                         aString _ 'default (', aStream contents asString, ')'].
  967.             minimum _ aString asSymbol]
  968.         ifFalse: [minimum _ box minimumValue].
  969.     aBox maximumValueIsDefault
  970.         ifTrue: 
  971.             [max _ box maximumValue.
  972.             max = nil
  973.                 ifTrue: [aString _ 'default (known after simulation)']
  974.                 ifFalse: [aStream _ TextStream on: 'default('.
  975.                         max printOn: aStream.
  976.                         aString _ 'default (',aStream contents asString, ')'].
  977.         maximum _ aString asSymbol]
  978.         ifFalse: [maximum _ box maximumValue].
  979.     self changed: #field!
  980.  
  981. initialize
  982.     field _ nil.
  983.     self changed: #field.!
  984.  
  985. update: anAspect with: aParameter
  986.     anAspect = #forBox:
  987.         ifTrue: [self forBox: aParameter].
  988.     anAspect = #currentBox
  989.         ifTrue: [self initialize].! !
  990.  
  991. !MinMaxEditor methodsFor: 'doIt/accept/explain'!
  992.  
  993. acceptText: aText from: aController 
  994.     "Text has been changed. Store or compile the text, depending on 
  995.     the current mode of the receiver."
  996.  
  997.     | val |
  998.     object class == CompiledMethod ifTrue: [^false].
  999.     field == nil ifTrue: [^false].
  1000.     val _ self
  1001.                 evaluateText: aText string
  1002.                 from: aController
  1003.                 ifFail: [^false].
  1004.     field = 'minimum'
  1005.         ifTrue: 
  1006.             [minimum _ val.
  1007.             box minimumValue: val].
  1008.     field = 'maximum'
  1009.         ifTrue: 
  1010.             [maximum _ val.
  1011.             box maximumValue: val].
  1012.     self changed: #text.
  1013.     ^true! !
  1014.  
  1015. !MinMaxEditor methodsFor: 'accessing'!
  1016.  
  1017. box
  1018.     ^box! !
  1019. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1020.  
  1021. MinMaxEditor class
  1022.     instanceVariableNames: ''!
  1023.  
  1024.  
  1025. !MinMaxEditor class methodsFor: 'instance creation'!
  1026.  
  1027. forBox:    aBox
  1028.     MinMaxView open: (self new forBox: aBox).! !
  1029.  
  1030. !MinMaxEditor class methodsFor: 'class initialization'!
  1031.  
  1032. flushMenu
  1033.     FieldList _ nil.! !
  1034.  
  1035. StandardSystemController subclass: #MinMaxController
  1036.     instanceVariableNames: ''
  1037.     classVariableNames: ''
  1038.     poolDictionaries: ''
  1039.     category: 'SDS-Graphs'!
  1040. MinMaxController comment:
  1041. 'Controller for triad MinMaxEditor (model)  - MinMaxView (view) - MinMaxController (controller)
  1042.     '!
  1043.  
  1044.  
  1045. !MinMaxController methodsFor: 'menu messages'!
  1046.  
  1047. resetToDefault
  1048.     model resetToDefault.! !